package com.jp.refreshlocalcacheserver.net.netty;

import com.jp.refreshlocalcacheserver.net.netty.message.RequestMessage;
import com.jp.refreshlocalcacheserver.net.netty.message.RequestMessageRegistry;
import com.jp.refreshlocalcacheserver.net.netty.session.ActiveSessionRegistry;
import com.jp.refreshlocalcacheserver.net.netty.session.SessionData;
import com.jp.refreshlocalcacheserver.net.netty.thread.DealMessagePoolService;
import com.jp.refreshlocalcacheserver.utils.ApplicationContextUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author: jipeng
 * @Description: 通道处理类
 * @Date: Created in 2020/5/12 11:30
 */
//Sharable 标识这类的实例之间可以在 channel 里面共享
@ChannelHandler.Sharable
public class EchoServerHandler extends SimpleChannelInboundHandler<String> {
    private Logger logger = LoggerFactory.getLogger(getClass());


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        int channelId = getChannelId(ctx.channel());
        logger.info("channelActive : OK ,  channelId: {} ", channelId);

        //创建会话数据并注册
        new SessionData(channelId,ctx);
        super.channelActive(ctx);
    }


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {

        String strMsg = (String) msg;
       try {
           channelRead0(ctx, strMsg);
       }catch (Exception e){
           logger.error("channelRead exception： {} ", ExceptionUtils.getStackTrace(e));
       }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
        logger.info("server received message : {} " , s);

        //分解消息
        String[] msgs = s.split(",");
        SessionData sessionData = ActiveSessionRegistry.getSessionData(getChannelId(ctx.channel()));
        dealMessage(sessionData,msgs);
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        int channelId = getChannelId(ctx.channel());
        logger.warn("channelId: {} link error",channelId);

        //删除会话数据
        ActiveSessionRegistry.deleteSessionData(channelId);

        cause.printStackTrace();
        ctx.close();
    }

    private int getChannelId(Channel channel){
        return channel.hashCode();
    }


    /**
     * 处理消息
     * @param sessionData
     * @param msgs
     */
    private void dealMessage(SessionData sessionData,String[] msgs){

        int msgID = Integer.valueOf(msgs[0]);

        RequestMessage rm;
        try {
            //获取消息类型的处理类
            RequestMessageRegistry requestMessageRegistry = ApplicationContextUtil.getBean(RequestMessageRegistry.class);
            rm = requestMessageRegistry.newRequestMessage(msgID);

            //给处理类赋值
            rm.setMsgId(msgID);
            rm.setSessionData(sessionData);
            rm.setContent(msgs[1]);

            //获取处理队列，把处理类扔到队列中
            DealMessagePoolService pool = ApplicationContextUtil.getBean(DealMessagePoolService.class);
            pool.execut(rm);
        }catch (Exception e){
            logger.error("handle message {} exception, error => {}",msgID, ExceptionUtils.getStackTrace(e));
        }
    }
}
